#pragma once
#include <iostream>
#include <unordered_map>
#include "../Connection.hpp"
#include "jsoncpp/json/json.h"
#include "Request&&Response.hpp"
#include "CreateRoom.hpp"
#include "JoinRoom.hpp"
#include "DestoryRoom.hpp"
#include "QuitRoom.hpp"
#include "ReadyRoom.hpp"
#include "CancelReadyRoom.hpp"
#include "PlayGameRoom.hpp"
#include "PlayerMove.hpp"
#include "SwordMove.hpp"

class ServerManager
{
public:
    ServerManager() {}

    void Init()
    {
        // _servers[CreateRoom] = std::make_pair(new RequestCreateRoom(), new ResponseCreateRoom());
        // _servers[JoinRoom] = std::make_pair(new RequestJoinRoom(), new ResponseJoinRoom());

        _servers.insert(CreateRoom);
        _servers.insert(JoinRoom);
        _servers.insert(DestoryRoom);
        _servers.insert(QuitRoom);
        _servers.insert(Ready);
        _servers.insert(CancelReady);
        _servers.insert(PlayGame);
        _servers.insert(PlayerMove);
        _servers.insert(SwordMove);

        _create_room = std::make_pair(new RequestCreateRoom(), new ResponseCreateRoom());
        _join_room = std::make_pair(new RequestJoinRoom(), new ResponseJoinRoom());
        _destory_room = std::make_pair(new RequestDestoryRoom(), new ResponseDestoryRoom());
        _quit_room = std::make_pair(new RequestQuitRoom(), new ResponseQuitRoom());
        _ready_room = std::make_pair(new RequestReadyRoom(), new ResponseReadyRoom());
        _cancel_ready_room = std::make_pair(new RequestCancelReadyRoom(), new ResponseCancelReadyRoom());
        _play_game_room = std::make_pair(new RequestPlayGameRoom(), new ResponsePlayGameRoom());
        _play_move = std::make_pair(new RequestPlayMove(), new ResponsePlayMove());
        _sword_move = std::make_pair(new RequestSwordMove(), new ResponseSwordMove());
    }

    // 获取一个请求报文解析请求类型，并根据对应的请求类型处理相应的请求事件，返回的是响应报文
    std::string GetRequsestAndResponse(const std::string &msg, bool *ok, Connection *conn)
    {
        *ok = true;
        Json::Value root;
        Json::Reader reader;
        reader.parse(msg, root);

        // 解析出请求报文中所携带的请求类型
        ServerType server_type = (ServerType)root["server_type"].asInt();
        // std::cout << "msg: " << msg << " " << server_type << std::endl;
        if (_servers.find(server_type) == _servers.end())
        {
            *ok = false;
            return "";
        }

        // std::cout << "msg: " << msg << " " << server_type << std::endl;
        // 报文的请求反序列化以及对请求的处理以及响应的序列化
        bool ret = false;
        std::string result;
        switch (server_type)
        {
        case CreateRoom:
            _create_room.first->Deserialize(root);
            ret = _create_room.second->ServerHandler(_create_room.first, conn);
            _create_room.second->Serialize(&result);
            break;
        case JoinRoom:
            _join_room.first->Deserialize(root);
            ret = _join_room.second->ServerHandler(_join_room.first, conn);
            _join_room.second->Serialize(&result);
            break;
        case DestoryRoom:
            // std::cout << "msg: " << msg << " " << server_type << std::endl;
            _destory_room.first->Deserialize(root);
            ret = _destory_room.second->ServerHandler(_destory_room.first, conn);
            _destory_room.second->Serialize(&result);
            break;
        case QuitRoom:
            _quit_room.first->Deserialize(root);
            ret = _quit_room.second->ServerHandler(_quit_room.first, conn);
            _quit_room.second->Serialize(&result);
            break;
        case Ready:
            _ready_room.first->Deserialize(root);
            ret = _ready_room.second->ServerHandler(_ready_room.first, conn);
            _ready_room.second->Serialize(&result);
            break;
        case CancelReady:
            _cancel_ready_room.first->Deserialize(root);
            ret = _cancel_ready_room.second->ServerHandler(_cancel_ready_room.first, conn);
            _cancel_ready_room.second->Serialize(&result);
            break;
        case PlayGame:
            _play_game_room.first->Deserialize(root);
            ret = _play_game_room.second->ServerHandler(_play_game_room.first, conn);
            _play_game_room.second->Serialize(&result);
            break;
        case PlayerMove:
            _play_move.first->Deserialize(root);
            ret = _play_move.second->ServerHandler(_play_move.first, conn);
            _play_move.second->Serialize(&result);
            break;
        case SwordMove:
            _sword_move.first->Deserialize(root);
            ret = _sword_move.second->ServerHandler(_sword_move.first, conn);
            _sword_move.second->Serialize(&result);
            break;
        default:
            break;
        }

        if (!ret)
        {
            *ok = false;
            return "";
        }

        *ok = true;
        return result;
    }

    std::pair<RequestCreateRoom *, ResponseCreateRoom *> GetCreateRoom()
    {
        return _create_room;
    }

    // std::string GetRequsestAndResponse(const std::string &msg, bool *ok, int fd)
    // {
    //     *ok = true;
    //     Json::Value root;
    //     Json::Reader reader;
    //     reader.parse(msg, root);

    //     // 解析出请求报文中所携带的请求类型
    //     ServerType server_type = (ServerType)root["server_type"].asInt();
    //     // std::cout << "msg: " << msg << " " << server_type << std::endl;
    //     if (_servers.find(server_type) == _servers.end())
    //     {
    //         *ok = false;
    //         return "";
    //     }

    //     // 报文的请求反序列化以及对请求的处理以及响应的序列化
    //     bool ret = false;
    //     std::string result;
    //     switch (server_type)
    //     {
    //     case CreateRoom:
    //         _create_room.first->Deserialize(root);
    //         ret = _create_room.second->ServerHandler(_create_room.first, fd);
    //         _create_room.second->Serialize(&result);
    //         break;
    //     case JoinRoom:
    //         _join_room.first->Deserialize(root);
    //         ret = _join_room.second->ServerHandler(_join_room.first, fd);
    //         _join_room.second->Serialize(&result);
    //         break;

    //     default:
    //         break;
    //     }
    //     // _servers[server_type].first->Deserialize(root);
    //     // std::cout << "msg: " << msg << " " << server_type << std::endl;
    //     // if (!_servers[server_type].second->ServerHandler(_servers[server_type].first, fd))
    //     if (!ret)
    //     {
    //         *ok = false;
    //         return "";
    //     }
    //     // std::cout << "msg: " << msg << " " << server_type << std::endl;
    //     // std::string result;
    //     // _servers[server_type].second->Serialize(&result);
    //     std::cout << result << std::endl;
    //     *ok = true;
    //     return result;
    // }

    void Destory()
    {
        delete _create_room.first;
        delete _create_room.second;

        delete _join_room.first;
        delete _join_room.second;

        delete _destory_room.first;
        delete _destory_room.second;

        delete _quit_room.first;
        delete _quit_room.second;

        delete _ready_room.first;
        delete _ready_room.second;

        delete _cancel_ready_room.first;
        delete _cancel_ready_room.second;

        delete _play_game_room.first;
        delete _play_game_room.second;

        delete _play_move.first;
        delete _play_move.second;

        delete _sword_move.first;
        delete _sword_move.second;

        // delete _servers[CreateRoom].first;
        // delete _servers[CreateRoom].second;

        // delete _servers[JoinRoom].first;
        // delete _servers[JoinRoom].second;
    }

    ~ServerManager() {}

private:
    std::set<ServerType> _servers;

    // std::unordered_map<ServerType, std::pair<Request *, Response *>> _servers;
    std::pair<RequestCreateRoom *, ResponseCreateRoom *> _create_room;
    std::pair<RequestJoinRoom *, ResponseJoinRoom *> _join_room;
    std::pair<RequestDestoryRoom *, ResponseDestoryRoom *> _destory_room;
    std::pair<RequestQuitRoom *, ResponseQuitRoom *> _quit_room;
    std::pair<RequestReadyRoom *, ResponseReadyRoom *> _ready_room;
    std::pair<RequestCancelReadyRoom *, ResponseCancelReadyRoom *> _cancel_ready_room;
    std::pair<RequestPlayGameRoom *, ResponsePlayGameRoom *> _play_game_room;
    std::pair<RequestPlayMove *, ResponsePlayMove *> _play_move;
    std::pair<RequestSwordMove *, ResponseSwordMove *> _sword_move;
};